from typing import TypeVar, Generic, Optional

from sqlalchemy.ext.asyncio.session import AsyncSession
from sqlalchemy import update, select, exists

from common.sqlalchemy_db import SqlalchemyX
from common.util import singleton
from modules.mod import Socket

T = TypeVar('T')


@singleton
class SocketService:
    def __init__(self, session: AsyncSession = SqlalchemyX.AsyncSessionLocal()):
        self.session = session

    async def create_socket(self, socket_content: dict) -> int:
        async with SqlalchemyX.AsyncSessionLocal() as session:
            socket_model = Socket(**socket_content)
            session.add(socket_model)
            await session.commit()
            await session.flush()
            return socket_model._id

    async def update_socket(self, option: dict, socket_content: dict):
        # 更新 socket 信息

        stmt = update(Socket).where(
            *[getattr(Socket, k) == v for k, v in option.items()]
        ).values(**socket_content)

        await self.session.execute(stmt)
        await self.session.commit()

    async def check_socket_existence(self, check_option: dict) -> bool:
        stmt = select(exists().where(Socket.__dict__[k] == v for k, v in check_option.items()))
        result = await self.session.execute(stmt)
        return result.scalar()

    async def get_socket_mes(self, option: dict) -> Optional[Socket]:
        stmt = select(Socket).filter_by(**option)
        result = await self.session.execute(stmt)
        return result.scalars().first()